package com.heima.wemedia.interceptor;

import com.heima.model.wemedia.pojos.WmUser;
import com.heima.utils.thread.WmThreadLocalUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Optional;

//wemedia服务的拦截器(从网关(wemedia.gateway.AuthorizeFilter(将userId存入header))过来的)
//前端请求过来时，携带了token，经过网关(wemedia.gateway.AuthorizeFilter)里的AuthorizeFilter解析token后，
//将用户信息存入header中，请求(携带了header)来到当前拦截器(本类)之后，
// 本类的作用：从header中获取userId，并放入ThreadLocal(当前线程)中


//想要它生效，还需要在heima-leadnews-service\heima-leadnews-wemedia\src\main\java\com\heima\wemedia\config
//里配置WebMvcConfig配置类，并重写addInterceptors方法，将本类添加进去
@Slf4j
public class WmTokenInterceptor implements HandlerInterceptor{
    //在请求处理之前进行调用（Controller方法调用之前）

    /**
     * 前置方法，在Controller方法执行之前执行
     * 得到header中的用户信息，并且放入当前线程ThreadLocal中
     * (前置用于将userId存入ThreadLocal中)
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle
    (HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //获取header中的userId(因为网关里的AuthorizeFilter.java下的filter写的是httpHeaders.add("userId", userId + "");)
        String userId = request.getHeader("userId");
        Optional<String> optional = Optional.ofNullable(userId);
        if(optional.isPresent()){
            //把用户id存入threadloacl中
            WmUser wmUser = new WmUser();
            wmUser.setId(Integer.valueOf(userId));
            WmThreadLocalUtil.setUser(wmUser);
            log.info("wmTokenFilter设置用户信息到threadlocal中...");
        }
//        if(userId != null){
//            //将包含userId的用户信息封装成对象，放入ThreadLocal中
//            WmUser wmUser = new WmUser();
//            wmUser.setId(Integer.valueOf(userId));
//            WmThreadLocalUtil.setUser(wmUser);//不能用WmThreadLocalUtil，需要针对app端创建一个AppThreadLocalUtil
//        }
        return true;
    }

//    /**
//     * 后置方法，在Controller方法执行之后，渲染视图之前执行
//     * (请求结束之后，将ThreadLocal的userId进行移除)
//     * @param request
//     * @param response
//     * @param handler
//     * @param modelAndView
//     * @throws Exception
//     */
//    @Override
//    //postHandle是后置处理，在Controller方法执行之后，如果抛了异常之后，他并不会执行清理WmThreadLocalUtil.clear();
//    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
////        WmThreadLocalUtil.clear();
//    }

    @Override
    // 所以新定义的拦截器是在当前的afterCompletion方法中清理，当前controller中的方法执行完成之后，如果执行抛出异常之后，
    // 他依然会执行当前的WmThreadLocalUtil.clear();清理WmThreadLocalUtil
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        WmThreadLocalUtil.clear();
    }
}
